﻿using System.Security.Cryptography;
using System.Threading;
using BizModels;
using HinokyWeb.Models;
using IRepositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Repositories;
using ViewModels.AccountVM;
using WebLib.AuthorizeService;
using WebLib.CryptoService;
using Microsoft.Web.WebPages.OAuth;
using DotNetOpenAuth.AspNet;
using ViewModels.MemberVM;
using WebLib.FileUpload;

namespace HinokyWeb.Controllers
{
    [Authorize(Roles = "ADMIN")]
    public class MemberController : Controller
    {
        private IMemberRepository _memberRepository;
        private IMemberProfileRepository _memberProfileRepository;
        private IFormsAuthentication _formsAuthentication;

        public MemberController()
        {
            _memberRepository = new MemberRepository();
            _memberProfileRepository = new MemberProfileRepository();
            _formsAuthentication = new DefaultFormsAuthentication();
        }

        [HttpGet]
        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult Login(LoginVM model, string returnUrl)
        {
            var userKey = _memberRepository.GetLogin(model.UserID, MD5Helper.GetMd5Hash(model.Password));

            if (userKey > 0)
            {
                var userInfo = _memberRepository.GetUserInfo(userKey);

                if (userInfo == null) return Json(new {Success = false});

                _formsAuthentication.SignIn(userKey, userInfo.UserID, userInfo.Name, userInfo.Roles);

                return Json(new { Success = true, ReturnUrl = returnUrl });
            }

            return Json(new { Success = false, Message = "계정정보가 틀립니다." });
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult ExternalLogin(string returnUrl)
        {
            return new ExternalLoginResult("facebook", Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
        }

        [AllowAnonymous]
        public ActionResult ExternalLoginCallback(string returnUrl)
        {
            AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
            
            if (result.IsSuccessful)
            {
                var userInfo = _memberRepository.GetUserInfo(result.ProviderUserId);

                if (userInfo != null)
                {
                    _formsAuthentication.SignIn(userInfo.UserKey, userInfo.UserID, userInfo.Name, userInfo.Roles);
                    return Redirect("/");
                }
                else        // 회원가입으로 이동해야함. 지금은 그냥 오류~!
                {
                    return RedirectToAction("ExternalLoginFailure");   
                }
            }

            return RedirectToAction("ExternalLoginFailure");
        }

        [AllowAnonymous]
        public ActionResult ExternalLoginFailure()
        {
            return View();
        }

        [HttpGet]
        [AllowAnonymous]
        public ActionResult GetUserProfile()
        {
            // 회원가입이 없기에 임시로 막아둡니다.
            //if (MemberInfo.Instance.UserKey == 0)
            //    return Json(new { IsLogin = false, UserId = "", UserName = string.Empty, NickName = string.Empty, ProfileImageUrl = string.Empty }, JsonRequestBehavior.AllowGet);

            // 비회원 회원 상관없이 운영자의 정보를 보게 됩니다.
            //var data = _memberProfileRepository.GetMemberProfile(MemberInfo.Instance.UserKey);
            var data = _memberProfileRepository.GetMemberProfile(1);

            if (data != null && data.UserKey != 0)
            {
                data.ProfileImageUrl = !string.IsNullOrEmpty(data.ProfileImageUrl) ? data.ProfileImageUrl.ToImageUrl() : string.Empty;
                return Json(new { IsLogin = true, UserId = data.UserId, UserName = data.UserName, NickName = data.NickName, ProfileImageUrl = data.ProfileImageUrl }, JsonRequestBehavior.AllowGet);
            }
            
            return Json(new { IsLogin = true, UserId = MemberInfo.Instance.UserID, UserName = MemberInfo.Instance.UserName, NickName = string.Empty, ProfileImageUrl = string.Empty }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult SetUserProfile(MemberProfileObjVM userProfile)
        {
            var memberProfileT = new MemberProfileT();

            if (string.IsNullOrEmpty(userProfile.FileName))  // 파일 업로드가 발생하지 않을 경우
            {
                memberProfileT.ProfileImageUrl = string.Empty;
                memberProfileT.ProfileImagePath = string.Empty;
            }
            else    // 파일 업로드가 발생한 경우
            {
                var imageData = userProfile.FileData.Split(',');
                if (imageData.Length > 1)
                {
                    var savedImageInfo = UploadHelper.UploadImageFile(Convert.FromBase64String(imageData[1]), userProfile.FileName);

                    memberProfileT.ProfileImageUrl = savedImageInfo;
                    memberProfileT.ProfileImagePath = savedImageInfo;
                }
            }

            memberProfileT.UserKey = MemberInfo.Instance.UserKey;
            memberProfileT.NickName = userProfile.NickName;
            memberProfileT.InsertDate = DateTime.Now;
            memberProfileT.UpdateDate = DateTime.Now;
            memberProfileT.InsertUserKey = MemberInfo.Instance.UserKey;
            memberProfileT.UpdateUserKey = MemberInfo.Instance.UserKey;

            var returnValue = _memberProfileRepository.SaveMemberProfile(memberProfileT);

            return Json(new { IsSuccess = returnValue > 0 }, JsonRequestBehavior.AllowGet);
        }

        [AllowAnonymous]
        public ActionResult LogOut()
        {
            MemberInfo.Instance = null;
            _formsAuthentication.SignOut();

            return Json(new { Success = true });
        }

        public ActionResult EditMyInfo()
        {
            return View();
        }

        internal class ExternalLoginResult : ActionResult
        {
            public ExternalLoginResult(string provider, string returnUrl)
            {
                Provider = provider;
                ReturnUrl = returnUrl;
            }

            public string Provider { get; private set; }
            public string ReturnUrl { get; private set; }

            public override void ExecuteResult(ControllerContext context)
            {
                OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
            }
        }

    }
}
